package org.redmagic.agent.location;

import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.annotation.Nonnull;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.redmagic.location.Location;
import org.redmagic.utils.Conditions;

public class ChainedLocation implements Location {

    private static final Log LOG = LogFactory.getLog(ChainedLocation.class);
    
    private final List<Location> locations;
    
    public ChainedLocation(List<Location> locations) {
        this.locations = Conditions.notNull(locations, "locations");
    }
    
    @Override
    @Nonnull
    public Properties resolvePlaceholders(Set<String> placeholders) {
        Set<String> unresolvedPlaceholders = new HashSet<String>(placeholders);
        Properties resolvedPlaceholders = checkLocations(unresolvedPlaceholders);
        return resolvedPlaceholders;
    }
    
    private Properties checkLocations(Set<String> unresolvedPlaceholders) {
        Properties resolvedProperties = new Properties();
        
        for (Location location : this.locations) {
            boolean finished = checkLocation(location, unresolvedPlaceholders, resolvedProperties);
            if (finished) {
                break;
            }           
        }
        
        return resolvedProperties;
    }
    
    private boolean checkLocation(Location location, Set<String> unresolvedPlaceholders, Properties resolvedProperties) {
        Properties results = location.resolvePlaceholders(unresolvedPlaceholders);
        LOG.info("Results from " + location + ": " + results);
        resolvedProperties.putAll(results);
        
        // remove placeholders we've found
        for (Object placeholder : results.keySet()) {
            unresolvedPlaceholders.remove(placeholder);
        }
        
        // end if there are no more placeholders to find
        return unresolvedPlaceholders.isEmpty();
    }

    
    @Override
    public void postProcess(Properties input) {
        for (Location location : this.locations) {
            location.postProcess(input);
        }
    }
}
